#include"ParseRequst.h"
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cerrno>
#include <fstream>
#include <dirent.h>
#include <sys/stat.h>
ParseRequest::ParseRequest()
{
    m_readbuffer=new Buffer(4028);
    m_writebuffer=new Buffer(4028);
}

ParseRequest:: ~ParseRequest()
{
    if(m_readbuffer){
        delete m_readbuffer;
    }
    if(m_writebuffer){
        delete m_writebuffer;
    }
}

int ParseRequest::Processingrequest(int fd)
{
     m_fd=fd;
     int flags=fcntl(fd,F_GETFL,0);
     fcntl(fd,F_SETFL,flags|O_NONBLOCK); //s设置为非阻塞
     //将数据读到buf中
     int ret=1;
     while(ret>0){
       ret=m_readbuffer->SocketRead(fd);
     }
     char*start=m_readbuffer->GetData()+m_readbuffer->GetReadPos();
     int index=0;
     while(start!=nullptr &&index<=3)
     {
        char*end=m_readbuffer->FindCRLF();
        if(end==nullptr && index<3){
           return 0;
        }
        if(end==nullptr &&index>=3){
           break;
        }
        char*space=strstr(m_readbuffer->GetData()+m_readbuffer->GetReadPos(),":");
        int linesize=space-start;  
        char buf[1024]={0};
        strncpy(buf,start,linesize);
        string key=buf;
        memset(buf,0,sizeof(buf));
        linesize=end-space-3;   
        strncpy(buf,space+2,linesize);
        string value=buf;
        RequstBody.push_back(body(key,value));
        m_readbuffer->readPosIncrease(end-start+4);
        start=m_readbuffer->GetData()+m_readbuffer->GetReadPos();
        index++;
     }
     return 1;
}

int ParseRequest::PerformActions()
{
    body temp=RequstBody[2];
    if(temp.key=="login")             //用户注册
    {
       
    }
    else if(temp.key=="register")     //用户登录
    {
        user_register(RequstBody[0].value,RequstBody[1].value,0);
    }
    else if(temp.key=="PlaySong")   //播放歌曲
    { 
        loadmusic();  //播放音乐
    }
    else if(temp.key=="RequestMusicList")//用户请求歌词目录
    {   
        string folderPath;
        int ret=RequestMusicList(folderPath,temp.value);
        if(ret==-1){
            //打开目录失败
            cout<<"RequestMusicList open dir error!!!"<<endl;
        }
    }
    else if(temp.key=="GainUseLoveList")
    {
        GainUseLoveList();
    }
    else if(temp.key=="AddLoveMusic")   //添加喜欢列表      
    {
        //删除歌曲
        //usrnameid:{1373474316}\r\npassword:{lyj137347}\r\nDelLoveMusic:{musicname}\r\n
        //添加歌曲
        //usrnameid:{1373474316}\r\npassword:{lyj137347}\r\nAddLoveMusic:{musicname}\r\n
        AddLoveMusic();
    }
    else if(temp.key=="DelLoveMusic")
    {
        DelLoveMusic();
    }
    return 0;  //没有匹配到客户端执行匹配的操作
}

void ParseRequest::loadmusic()
{
    string filename="songlist/";
    filename.append(RequstBody[2].value);
    filename.append(".mp3");
    if(chdir("songlist/")==-1)  //切换到歌曲工作目录
    {
        cout<<"切换失败"<<endl;
        return ;
    }
    int fd=open(filename.c_str(),O_RDONLY);
    if(fd==-1){
        cout<<"open is error"<<endl;
        return ;
    }
    char*buf=new char[1024];
    int ret=0; 
    int ret1=0;
    do{
        ret1=read(fd,buf,sizeof(buf));
        ret+=ret1;
        if(ret1>0)
        {
           int temp=write(m_fd,buf,ret1);
           if (temp == -1) 
           {
              if (errno == EPIPE || errno == ECONNRESET) //客户端关闭文件描述符
              {
                //对端关闭
                break;
              }
           }
        }
        //usleep(1);
    }while(ret1>0);
    delete buf;
}
#include<map>
int ParseRequest::user_register(string nameid,string passwd,string &name)
{
    int ret=mysqlinit();
    int res1=-1;
    if(ret==-1)
    {
        //数据库初始化失败 
        cout<<"数据库初始化失败"<<endl;
        mysql_close(m_mysql);
        m_mysql=nullptr;
        return res1;
    }
    connectmysql();   //连接数据库
    //select *from uses where usrnameid="1373474316" and passwd= "137347";
    string sql;
    sql.append("select *from MusicServer.user where usrnameid=\"");
    sql.append(nameid);
    sql.append("\" AND passwd=\"");
    sql.append(passwd);
    sql.append("\";");
    int result =mysql_query(m_mysql,sql.c_str()); 
    if(result>=0) //执行mysql语句
    {     
      MYSQL_RES* res = mysql_store_result(m_mysql); //获取结果集合
      if (res != NULL) 
      {
        MYSQL_FIELD* results = mysql_fetch_field(res);  //获取表的全部信息; 
        if(mysql_fetch_row(res)!=nullptr)   //有数据库信息
        {  
            //将用户名字查询出来
            //select name from uses where usernameid="1373474316";
            res1=1;  //登录成功
        }
        else
        {
            res1=-1;  // 登录失败  
        }
      }
      mysql_free_result(res);
    }
    mysql_close(m_mysql);
    m_mysql=nullptr;
    return res1; 
}

int ParseRequest::user_register(string nameid, string passwd, int res)
{
     string name;
     res=user_register(nameid, passwd,name);
     string str;
     if(res==1)  //用户登录成功
     {
         //select name from MusicServer.user where usernameid="1373474316";
         string sql;
         sql.append("select name from MusicServer.user where usrnameid=\"");
         sql.append(nameid);
         sql.append("\"");
         //查询用户name
         name=Queryfield(sql);

         str.append("Responsecode:{ok}\\r\\n");
         str.append("usernameid:{");
         str.append(nameid);
         str.append("}\\r\\nregister:{OK}\\r\\n");
         str.append(name);
         str.append("\\0");
         m_writebuffer->AppendString(str.c_str());
     }
     else       //用户登录失败
     {
         str.append("Responsecode:{ok}\\r\\n");
         str.append("usrnameid:{");
         str.append(nameid);
         str.append("}\\r\\nregister:{notfound}\\r\\n");
         str.append("\\0");
         m_writebuffer->AppendString(str.c_str());
     }
     m_writebuffer->SendData(m_fd);
}

std::string removeFileExtension(const std::string& fileName)   //去掉文件后缀
{
    size_t pos = fileName.find_last_of('.');
    if (pos != std::string::npos) {
        return fileName.substr(0, pos);
    }
    return fileName;
}


int ParseRequest::RequestMusicList(string folderPath,string dir1)
{
    if(dir1=="每日推荐")
    {
        folderPath.append("songlist");
    }     
    list<string>fileTitles;
    DIR* dir = opendir(folderPath.c_str());
    if (dir == nullptr) 
    {
        std::cerr << "Failed to open directory: " << folderPath << std::endl;
        return -1;
    }   
    dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        std::string fileName = entry->d_name;
        std::string filePath = folderPath + "/" + fileName;

        struct stat fileStat;
        if (stat(filePath.c_str(), &fileStat) == -1) {
            continue;  // 获取文件信息失败，跳过当前文件
        }

        if (S_ISDIR(fileStat.st_mode)) {
            continue;  // 是目录，跳过当前文件
        }

        std::string fileTitle = removeFileExtension(fileName);  //去掉文件后缀
        fileTitles.push_back(fileTitle);
    }
    closedir(dir);
    //回发数据 每一首音乐 | 结尾
    
    while(!fileTitles.empty())
    {
        string s=fileTitles.back();
        m_writebuffer->AppendString(s.c_str());
        m_writebuffer->AppendString("|");
        fileTitles.pop_back();
    }  
    m_writebuffer->SendData(m_fd);
    return 0;
}

int ParseRequest::AddLoveMusic()
{
    string musicname=RequstBody[2].value;
    string response;
    if(addmusic(musicname)==1)
    {
        //Responsecode:{ok}\r\n     //OK成功  NoFound //没有找到资源
        //usrnameid:{}\r\n  
        //AddLoveMusic:{success}\r\n
        
        response.append("Responsecode:{ok}\\r\\n").append("usrnameid:{")
        .append(RequstBody[0].value).append("}\\r\\n").append("AddLoveMusic:{success}\\r\\n");
           
    }
    else
    {
        response.append("Responsecode:{ok}\\r\\n").append("usrnameid:{")
        .append(RequstBody[0].value).append("}\\r\\n").append("AddLoveMusic:{Failing}\\r\\n");
    }
    m_writebuffer->AppendString(response.c_str());
    m_writebuffer->SendData(m_fd);
    return 0;
}

int ParseRequest::DelLoveMusic()
{
    string musicname=RequstBody[2].value;
    string response;
    if(delmusic(musicname)==1)
    {
        //Responsecode:{ok}\r\n     //OK成功  NoFound //没有找到资源
        //usrnameid:{}\r\n  
        //DelLoveMusic:{success}\r\n
        response.append("Responsecode:{ok}\\r\\n").append("usrnameid:{")
        .append(RequstBody[0].value).append("}\\r\\n").append("DelLoveMusic:{success}\\r\\n");
           
    }
    else
    {
        response.append("Responsecode:{ok}\\r\\n").append("usrnameid:{")
        .append(RequstBody[0].value).append("}\\r\\n").append("DelLoveMusic:{Failing}\\r\\n");
    }
    m_writebuffer->AppendString(response.c_str());
    m_writebuffer->SendData(m_fd);
    return 0;
}

int ParseRequest::GainUseLoveList()
{
    list<string>MusicList=GetMusiclovelist();
    while(!MusicList.empty())
    {
        this->m_writebuffer->AppendString(MusicList.front().c_str());
        this->m_writebuffer->AppendString("\n");
        MusicList.pop_front();
    }
    //发送数据
    this->m_writebuffer->SendData(m_fd);
    return 0;
}
// mode：打开文件的模式，用于指定对文件的操作方式，可以是以下之一：
// "r": 打开一个已有的文本文件，只允许读取。
// "w": 创建一个新的文本文件，允许写入，如果文件已存在，则将其内容清空。
// "a": 打开一个文本文件以进行追加操作，在文件末尾添加新内容，如果文件不存在则创建。
// "rb", "wb", "ab": 类似于上述模式，但用于二进制文件。
list<string> ParseRequest::GetMusiclovelist()
{
    string nameid=RequstBody[0].value;   //nameid
    string passwd=RequstBody[1].value;   //passwd
    list<string>MusicList;
    FILE *file;
    //身份验证 
    if(authentication())  //成功
    {
         string filepath=GetUserPath(nameid,passwd); //获取用户文件路径
         file=openfile(filepath,"r");
         //一行一行读取数据
        char buffer[1024];
        while (fgets(buffer, sizeof(buffer), file) != NULL)
        {
            int bufferSize = sizeof(buffer);
            buffer[bufferSize - 1] = '\0';  // 将最后一个字符设为字符串结束符
            size_t newLinePos = strcspn(buffer, "\n");  // 找到换行符的位置
            if (newLinePos < bufferSize)
            {
                buffer[newLinePos] = '\0';  // 将换行符替换为字符串结束符
            }
            MusicList.push_back(buffer);    // 将歌曲读进 MusicList 中
        }
    }
    else
    {
          return list<string>();
    }
    fclose(file);
    return MusicList;  //返回列表
}

int ParseRequest::authentication()  
{
    //身份验证 
    string nameid=RequstBody[0].value;   //nameid
    string passwd=RequstBody[1].value;   //passwd
    string name;
    int ret=user_register(nameid,passwd,name);
    return ret;
}

FILE *ParseRequest::openfile(string filepath, string flags)
{
    FILE *file =fopen(filepath.c_str(),flags.c_str());
    if(file==nullptr)
    {
        cout<<"File:"<<filepath<<"open error!"<<endl;
        return nullptr;
    }
    return file;
}

int ParseRequest::addmusic(string musicname)
{
    //身份验证
    if(authentication())  //通过
    {
        list<string>MusicList=GetMusiclovelist();  //获取到用户喜欢的列表
        //判断重复没有
        auto it=MusicList.begin();
        while(it!=MusicList.end())
        {
            if(*it==musicname)
            {
                return 1;  // 在喜欢列表中不需要添加歌曲
            }
            it++;
        }
        //添加在喜欢文件中
        // 检查文件是否为空
        string filepath=GetUserPath(RequstBody[0].value,RequstBody[1].value);
        FILE*file=openfile(filepath,"a");
        fseek(file, 0, SEEK_END);  // 将文件指针移动到文件末尾
        long fileSize = ftell(file);  // 获取文件大小
        if (fileSize == 0) {
            fprintf(file, "%s", musicname.c_str());  // 文件为空，直接写入音乐名称
        } 
        else 
        {
            fprintf(file, "\n%s", musicname.c_str());  // 文件不为空，在音乐名称前加上换行符
        } 
        fclose(file);  // 关闭文件
    }
    else
    {
        return -1;  //添加失败
    }
    return 1; 
}

int ParseRequest::delmusic(string delmusicname)
{
    //身份验证
    if(authentication())  //通过
    {
        list<string>MusicList=GetMusiclovelist();  //获取到用户喜欢的列表
        //判断重复没有
        auto it=MusicList.begin();
        while(it!=MusicList.end())
        {
            if(*it==delmusicname)  //判断要删除的列表是否在喜欢列表中
            {
                MusicList.erase(it);  // 删除找到的音乐
                string filepath=GetUserPath(RequstBody[0].value,RequstBody[1].value);
                FILE*file=openfile(filepath,"w");  //写进文件中
                while(!MusicList.empty())
                {
                    fprintf(file, "%s\n",MusicList.front().c_str());  // 文件不为空，在音乐名称前加上换行符
                    MusicList.pop_front();
                }
                fclose(file);
                break;  
            }
        }
    }
    else
    {
        return -1;  //删除失败
    }
    return 1; 
}

string ParseRequest::GetUserPath(string nameid, string passwd)
{
    //查询出用户喜欢列表文件
    string sql;
    //select address from user where usrnameid="1373474316" and passwd="137347";
    sql.append("select address from MusicServer.user where usrnameid=\"").append(nameid).append("\" AND ");
    sql.append("passwd=\"").append(passwd).append("\";");
    string filepath="user/";
    filepath.append(Queryfield(sql));  //获取到用户文件
    filepath.append("/lovemusic.txt");
    return filepath;
}


void ParseRequest::connectmysql(const char *honst, const char *usr, const char *passwd)
{
	MYSQL* conn = mysql_real_connect(m_mysql, honst, usr, passwd, NULL, 3306, NULL, 0);
    if (conn == NULL) {
		cout << "mysql_real_connect is error" << mysql_errno(m_mysql) << endl;
		exit(-1);
	}
	mysql_set_character_set(m_mysql, "utf8mb4");
}

int ParseRequest::mysqlinit()
{
    m_mysql = mysql_init(m_mysql);
	if (m_mysql == NULL) 
    {
		return -1;
    }
    return 1;
}

string ParseRequest::Queryfield(string sql)
{
    string str;
    int ret=mysqlinit();
    if(ret==-1)
    {
        //数据库初始化失败 
        cout<<"数据库初始化失败"<<endl;
        return str;
    }
    connectmysql();   //连接数据库  
    int result =mysql_query(m_mysql,sql.c_str());
    if(result>=0)
    {
       MYSQL_RES* res = mysql_store_result(m_mysql); //获取结果集合
        if (res != NULL) 
        {
           MYSQL_FIELD* results = mysql_fetch_field(res);  //获取表的全部信息
           int nums = mysql_num_fields(res);
           MYSQL_ROW row;
           while ((row = mysql_fetch_row(res)) != NULL) 
           {
               for (int i = 0; i < nums; i++) 
               {
                    str.append(row[i]);
               }
           }
        }
        mysql_free_result(res);
    }
    mysql_close(m_mysql);
    m_mysql=nullptr;
    //cout<<"Queryfield:"<<str<<endl;
    return str;
}
